package ccm.component.oscilloscope;

import ccm.common.Crc;
import ccm.common.ReceiveDataEvent;
import ccm.common.ReceiveDataListener;

import java.util.Arrays;

public class VisualScopeDataManager extends OscilloscopeDataManager implements ReceiveDataListener
{
    /**
     * 接收缓冲
     */
    protected final byte[] receiveBuf;
    /**
     * 接收缓冲起始
     */
    protected int receiveBufStart;
    /**
     * 接收缓冲是否满了
     */
    protected boolean receiveBufFull;

    public VisualScopeDataManager()
    {
        super();
        receiveBuf=new byte[10];
        receiveBufStart=0;
    }

    /**
     * 获取一共有几列
     *
     * @return 列数
     */
    @Override
    public int getDataColumn()
    {
        return 4;
    }

    /**
     * 接收到数据事件
     */
    @Override
    public void receiveData(ReceiveDataEvent event)
    {
        synchronized(receiveBuf)
        {
            for(byte datum: event.getData())
            {
                receiveBuf[receiveBufStart]=datum;
                ++receiveBufStart;
                if(receiveBufStart>=receiveBuf.length)
                {
                    receiveBufFull=true;
                    receiveBufStart=0;
                }
                if(crcCheck())
                {
                    float[] ans=new float[4];
                    for(int i=0;i<4;++i){ans[i]=(short)(((receiveBuf[(i*2+receiveBufStart)%receiveBuf.length]&0XFF)|((receiveBuf[(i*2+1+receiveBufStart)%receiveBuf.length]&0XFF)<<8))&0XFFFF);}
                    receiveBufStart=0;
                    receiveBufFull=false;
                    Arrays.fill(receiveBuf,(byte)0);

                    dataList.add(new TimeAndData(event.getTimeUs(),ans));

                }
            }
        }
    }

    /**
     * 对数据缓存区域进行CRC校验
     *
     * @return true表示通过校验
     * false表示未通过校验
     */
    private boolean crcCheck()
    {
        synchronized(receiveBuf)
        {
            if(!receiveBufFull){return false;}
            int ans=(((receiveBuf[(8+receiveBufStart)%receiveBuf.length]&0XFF)|((receiveBuf[(9+receiveBufStart)%receiveBuf.length]&0XFF)<<8))&0XFFFF);
            return Crc.crc16Modbus(receiveBuf,receiveBufStart,8)==ans;
        }
    }
}
